package com.func.domain.strategy.service.rule.tree.factory.engine.impl;

import com.func.domain.strategy.model.valobj.RuleLogicCheckTypeVO;
import com.func.domain.strategy.model.valobj.RuleTreeNodeLineVO;
import com.func.domain.strategy.model.valobj.RuleTreeNodeVO;
import com.func.domain.strategy.model.valobj.RuleTreeVO;
import com.func.domain.strategy.service.rule.tree.ILogicTreeNode;
import com.func.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import com.func.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @version 1.0
 * @className DecisionTreeEngine
 * @description 决策树引擎实现类
 * @author: func
 * @date 2025/2/28 21:15
 */

@AllArgsConstructor
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {
    private RuleTreeVO ruleTree;
    private Map<String, ILogicTreeNode> logicRuleTreeNodeGroup;

    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyId, Integer awardId, Date endDateTime) {

        // 获取基础信息
        Map<String, RuleTreeNodeVO> treeNodeGroup = ruleTree.getTreeNodeMap();
        String nextNode = ruleTree.getTreeRootRuleNode();

        // 获取起始节点, 也是当前节点
        RuleTreeNodeVO ruleTreeNode = treeNodeGroup.get(nextNode);

        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;
        // 遍历这颗树, 直到叶子节点
        while (null != nextNode) {
            // 获取决策节点
            ILogicTreeNode logicTreeNode = logicRuleTreeNodeGroup.get(nextNode);
            String ruleValue = ruleTreeNode.getRuleValue();

            // 决策节点执行过滤
            DefaultTreeFactory.TreeActionEntity treeActionEntity = logicTreeNode.logic(userId, strategyId, awardId, ruleValue, endDateTime);
            RuleLogicCheckTypeVO ruleLogicCheckType = treeActionEntity.getRuleLogicCheckType();
            strategyAwardVO = treeActionEntity.getStrategyAwardVO();
            log.info("决策树引擎 [{}] treeId : {}, node:{}, code:{}", ruleTree.getTreeName(), ruleTree.getTreeId(), nextNode, ruleLogicCheckType.getCode());

            // 获取下一个节点
            nextNode = nextNode(ruleLogicCheckType.getCode() ,ruleTreeNode.getTreeNodeLineList());
            ruleTreeNode = treeNodeGroup.get(nextNode);
        }

        return strategyAwardVO;
    }

    /**
     * 根据边List获取到这个节点的下一个节点
     * @param matterValue 当前规则树节点的RuleLogicCheckTypeVo的值
     * @param ruleTreeNodeLineList
     * @return
     */
    public String nextNode(String matterValue, List<RuleTreeNodeLineVO> ruleTreeNodeLineList) {
        // 出边集合为空, 也就是这个节点就是叶子节点的时候
        if (null == ruleTreeNodeLineList || 0 == ruleTreeNodeLineList.size()){
            return null;
        }
        for (RuleTreeNodeLineVO ruleTreeNodeLine : ruleTreeNodeLineList) {
            if (decisionLogic(matterValue ,ruleTreeNodeLine)){
                return ruleTreeNodeLine.getRuleNodeTo();
            }
        }
        return null;
    }

    public boolean decisionLogic(String matterValue, RuleTreeNodeLineVO ruleTreeNodeLine) {
        switch (ruleTreeNodeLine.getRuleLimitType()) {
            case EQUAL:
                return ruleTreeNodeLine.getRuleLimitValue().getCode().equals(matterValue);
            // 后面的规则先省略
            case GE:
            case LE:
            case GT:
            case LT:
            case ENUM:
            default:
                return false;
        }
    }

}




